package br.com.saeng2D.analiseLxSi;

import java.util.ArrayList;

public class MatrizCrammer {
	
	private ArrayList<String> expressaoM= new ArrayList<String>();
	private ArrayList<String> grupoM = new ArrayList<String>();
	private ArrayList<String> expressaoFx = new ArrayList<String>();
	private ArrayList<String> expressaoFy = new ArrayList<String>();
	private ArrayList<String> resultados = new ArrayList<String>();
	private ArrayList<String> variaveis = new ArrayList<String>();
	private ArrayList<String> valorVariaveis = new ArrayList<String>();	
	private double [][] matrizCrammer = new double[3][3];
		
	public MatrizCrammer(String equacao1, String equacao2, String equacao3) throws Exception{
		ScannerLex analisador = new ScannerLex(equacao1);
		expressaoM= analisador.retornaExpressao();
		grupoM = analisador.retornaGrupoTermo();
		
		analisador = new ScannerLex(equacao2);
		expressaoFx = analisador.retornaExpressao();
				
		analisador = new ScannerLex(equacao3);
		expressaoFy = analisador.retornaExpressao();
		
		resultados.add(expressaoM.get(expressaoM.size()-1));
		resultados.add(expressaoFx.get(expressaoFx.size()-1));
		resultados.add(expressaoFy.get(expressaoFy.size()-1));
		
		preencheMatrizCrammer();
		
		/*for(int j =0;j<3;j++){
			for(int i=0;i<3;i++){
				System.out.print(matrizCrammer[j][i] + " ");
			}
			System.out.println("");
		}*/
		
		acharValorVariaveis(matrizCrammer);
		/*System.out.println(valorVariaveis);*/
		
	}
	public void preencheMatrizCrammer(){
		for(int i=0;i<expressaoM.size();i++){
			if(grupoM.get(i)=="variavel"){
				variaveis.add(expressaoM.get(i)); 
			}
		}		
		//primeira variavel
		for(int i=0;i<expressaoM.size();i++){
			if(expressaoM.get(i).equals(variaveis.get(0))){
				if(expressaoM.get(i+1).equals("*")&& expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][0] = Double.parseDouble(expressaoM.get(i+2));
				}else if(expressaoM.get(i+1).equals("*")&& expressaoM.get(i+2).equals("-0.0")){
					matrizCrammer[0][0] = Double.parseDouble(expressaoM.get(i+2))*-1;
				}else if(expressaoM.get(i+1).equals("*")&& !expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][0] = Double.parseDouble(expressaoM.get(i+2));
				}else if(expressaoM.get(i+1).equals("+")||expressaoM.get(i+1).equals("-")||expressaoM.get(i+1).equals("=")){
					matrizCrammer[0][0] = Double.parseDouble("1");
				}
			}	
		}
		for(int i=0;i<expressaoM.size();i++){
			if(expressaoM.get(i).equals(variaveis.get(1))){
				if(expressaoM.get(i+1).equals("*")&& expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][1] = Double.parseDouble(expressaoM.get(i+2))*-1.0;
				}else if(expressaoM.get(i+1).equals("*")&& !expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][1] = Double.parseDouble(expressaoM.get(i+2));
				}else if(expressaoM.get(i+1).equals("+")||expressaoM.get(i+1).equals("-")||expressaoM.get(i+1).equals("=")){
					matrizCrammer[0][1] = Double.parseDouble("1");
				}
			}
		}
		for(int i=0;i<expressaoM.size();i++){
			if(expressaoM.get(i).equals(variaveis.get(2))){
				if(expressaoM.get(i+1).equals("*")&& expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][2] = Double.parseDouble(expressaoM.get(i+2))*-1.0;
				}else if(expressaoM.get(i+1).equals("*")&& !expressaoM.get(i+2).equals("0")){
					matrizCrammer[0][2] = Double.parseDouble(expressaoM.get(i+2));
				}else if(expressaoM.get(i+1).equals("+")||expressaoM.get(i+1).equals("-")||expressaoM.get(i+1).equals("=")){
					matrizCrammer[0][2] = Double.parseDouble("1");
				}
			}
		}
		//segunda variavel
		for(int i=0;i<expressaoFx.size();i++){
			if(expressaoFx.get(i).equals(variaveis.get(0))){
				if(expressaoFx.get(i+1).equals("*")&& expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][0] = Double.parseDouble(expressaoFx.get(i+2))*-1.0;
				}else if(expressaoFx.get(i+1).equals("*")&& !expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][0] = Double.parseDouble(expressaoFx.get(i+2));
				}else if(expressaoFx.get(i+1).equals("+")||expressaoFx.get(i+1).equals("-")||expressaoFx.get(i+1).equals("=")){
					matrizCrammer[1][0] = Double.parseDouble("1");
				}
			}
		}
		for(int i=0;i<expressaoFx.size();i++){
			if(expressaoFx.get(i).equals(variaveis.get(1))){
				if(expressaoFx.get(i+1).equals("*")&& expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][1] = Double.parseDouble(expressaoFx.get(i+2))*-1.0;
				}else if(expressaoFx.get(i+1).equals("*")&& !expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][1] = Double.parseDouble(expressaoFx.get(i+2));
				}else if(expressaoFx.get(i+1).equals("+")||expressaoFx.get(i+1).equals("-")||expressaoFx.get(i+1).equals("=")){
					matrizCrammer[1][1] = Double.parseDouble("1");
				}
			}
		}
		for(int i=0;i<expressaoFx.size();i++){
			if(expressaoFx.get(i).equals(variaveis.get(2))){
				if(expressaoFx.get(i+1).equals("*")&& expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][2] = Double.parseDouble(expressaoFx.get(i+2))*-1.0;
				}else if(expressaoFx.get(i+1).equals("*")&& !expressaoFx.get(i+2).equals("0")){
					matrizCrammer[1][2] = Double.parseDouble(expressaoFx.get(i+2));
				}else if(expressaoFx.get(i+1).equals("+")||expressaoFx.get(i+1).equals("-")||expressaoFx.get(i+1).equals("=")){
					matrizCrammer[1][2] = Double.parseDouble("1");
				}
			}
		}
		//terceira variavel
		for(int i=0;i<expressaoFy.size();i++){
			if(expressaoFy.get(i).equals(variaveis.get(0))){
				if(expressaoFy.get(i+1).equals("*")&& expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][0] = Double.parseDouble(expressaoFy.get(i+2))*-1.0;
				}else if(expressaoFy.get(i+1).equals("*")&& !expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][0] = Double.parseDouble(expressaoFy.get(i+2));
				}else if(expressaoFy.get(i+1).equals("+")||expressaoFy.get(i+1).equals("-")||expressaoFy.get(i+1).equals("=")){
					matrizCrammer[2][0] = Double.parseDouble("1");
				}
			}
		}
		for(int i=0;i<expressaoFy.size();i++){
			if(expressaoFy.get(i).equals(variaveis.get(1))){
				if(expressaoFy.get(i+1).equals("*")&& expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][1] = Double.parseDouble(expressaoFy.get(i+2))*-1.0;
				}else if(expressaoFy.get(i+1).equals("*")&& !expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][1] = Double.parseDouble(expressaoFy.get(i+2));
				}else if(expressaoFy.get(i+1).equals("+")||expressaoFy.get(i+1).equals("-")||expressaoFy.get(i+1).equals("=")){
					matrizCrammer[2][1] = Double.parseDouble("1");
				}
			}
		}
		for(int i=0;i<expressaoFy.size();i++){
			if(expressaoFy.get(i).equals(variaveis.get(2))){
				if(expressaoFy.get(i+1).equals("*")&& expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][2] = Double.parseDouble(expressaoFy.get(i+2))*-1.0;
				}else if(expressaoFy.get(i+1).equals("*")&& !expressaoFy.get(i+2).equals("0")){
					matrizCrammer[2][2] = Double.parseDouble(expressaoFy.get(i+2));
				}else if(expressaoFy.get(i+1).equals("+")||expressaoFy.get(i+1).equals("-")||expressaoFy.get(i+1).equals("=")){
					matrizCrammer[2][2] = Double.parseDouble("1");
				}
			}
		}
		
	}
	public void acharValorVariaveis(double [][] matriz){
		double [][]matrizOriginal =new double[3][3];
		for (int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				matrizOriginal[i][j]= matriz[i][j];
			}
		}
		double detG = retornaDeterminante(matriz);
		double detV1;
		double detV2;
		double detV3;
				
		
		matriz[0][0]=Double.parseDouble(resultados.get(0));
		matriz[1][0]=Double.parseDouble(resultados.get(1));
		matriz[2][0]=Double.parseDouble(resultados.get(2));
		
		detV1 = retornaDeterminante(matriz);
		for (int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				matriz[i][j]= matrizOriginal[i][j];
			}
		}
		
		matriz[0][1]=Double.parseDouble(resultados.get(0)); 
		matriz[1][1]=Double.parseDouble(resultados.get(1));
		matriz[2][1]=Double.parseDouble(resultados.get(2));
		
		detV2 = retornaDeterminante(matriz);
		for (int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				matriz[i][j]= matrizOriginal[i][j];
			}
		}
		
		matriz[0][2]=Double.parseDouble(resultados.get(0));
		matriz[1][2]=Double.parseDouble(resultados.get(1));
		matriz[2][2]=Double.parseDouble(resultados.get(2));
		
		detV3 = retornaDeterminante(matriz);
		
		Double variavel1 = detV1/detG;
		Double variavel2 = detV2/detG;
		Double variavel3 = detV3/detG;
		
		if(variavel1==-0){
			variavel1*=-1;			
		}
		if(variavel2==-0){
			variavel2*=-1;		
		}
		if(variavel3==-0){
			variavel3*=-1;
		}
			
		
		valorVariaveis.add(variaveis.get(0)+" = "+Double.toString(variavel1));
		valorVariaveis.add(variaveis.get(1)+" = "+Double.toString(variavel2));
		valorVariaveis.add(variaveis.get(2)+" = "+Double.toString(variavel3));
		
		
	}
	public double retornaDeterminante(double [][] matriz){
		double det = 	((matriz[0][0] * matriz[1][1] * matriz[2][2])
						+(matriz[0][1] * matriz[1][2] * matriz[2][0])
						+(matriz[0][2] * matriz[1][0] * matriz[2][1]))
					   -((matriz[0][2] * matriz[1][1] * matriz[2][0])
						+(matriz[0][0] * matriz[1][2] * matriz[2][1])
						+(matriz[0][1] * matriz[1][0] * matriz[2][2]));
		return det;
	}
	
	public ArrayList<String> retornaValorVariaveis(){
		
		return valorVariaveis;
	}
	

}
